package com.shenchuangit.tm.sdk;

import com.fasterxml.jackson.databind.JsonNode;
import com.shenchuangit.tm.sdk.util.CommonUtils;
import com.shenchuangit.tm.sdk.util.SignatureUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;

import java.util.Collections;

/**
 * 腾讯会议接口
 *
 * @author FlyFive
 */
public class TencentMeetingClient {
    public static final Logger logger = LoggerFactory.getLogger(TencentMeetingClient.class);

    public static String SECRET_ID;
    public static String SECRET_KEY;
    public static String APP_ID;
    public static String SDK_ID;
    public static String BASE_URL = "https://api.meeting.qq.com/";

    private static TencentMeetingClient client;

    public TencentMeetingClient() {
    }

    public TencentMeetingClient(String secretId, String secretKey, String appId, String sdkId) {
        SECRET_ID = secretId;
        SECRET_KEY = secretKey;
        APP_ID = appId;
        SDK_ID = sdkId;
    }

    /**
     * 获取客户端单例
     *
     * @return 实例化的客户端
     */
    public static TencentMeetingClient getInstance() {
        return client;
    }

    /**
     * 初始化 客户端 单例参数
     *
     * @param secretId  secretId
     * @param secretKey secretKey
     * @param appId     appId
     * @param sdkId     sdkId
     */
    public static void init(String secretId, String secretKey, String appId, String sdkId) {
        client = new TencentMeetingClient(secretId, secretKey, appId, sdkId);
    }

    /**
     * 请求（GET)
     * 官方文档说明：get请求requestBody直接空串即可
     *
     * @param uri 请求路径（相对路径）
     * @return 构造好的请求头
     */
    public String get(String uri) {
        HttpHeaders headers = initHttpHeaders(uri, HttpMethod.GET, null);
        HttpEntity<JsonNode> request = new HttpEntity<>(null, headers);

        ResponseEntity<String> resultEntity = CommonUtils.getSingletonRestTemplate().exchange(BASE_URL + uri, HttpMethod.GET, request, String.class);

        return resultEntity.getBody();
    }

    /**
     * 请求（POST）
     *
     * @param uri         请求路径（相对路径）
     * @param requestBody 请求体数据（JSON对象）
     * @return 构造好的请求头
     */
    public String post(String uri, JsonNode requestBody) {
        HttpHeaders headers = initHttpHeaders(uri, HttpMethod.POST, requestBody);
        HttpEntity<JsonNode> request = new HttpEntity<>(requestBody, headers);

        ResponseEntity<String> resultEntity = CommonUtils.getSingletonRestTemplate().exchange(BASE_URL + uri, HttpMethod.POST, request, String.class);

        return resultEntity.getBody();
    }

    /**
     * 请求（PUT）
     *
     * @param uri         请求路径（相对路径）
     * @param requestBody 请求体数据（JSON对象）
     * @return 构造好的请求头
     */
    public String put(String uri, JsonNode requestBody) {
        HttpHeaders headers = initHttpHeaders(uri, HttpMethod.PUT, requestBody);
        HttpEntity<JsonNode> request = new HttpEntity<>(requestBody, headers);

        ResponseEntity<String> resultEntity = CommonUtils.getSingletonRestTemplate().exchange(BASE_URL + uri, HttpMethod.PUT, request, String.class);

        return resultEntity.getBody();
    }

    /**
     * 构造请求头，将公共参数设置好
     *
     * @param uri         请求路径（相对路径）
     * @param httpMethod  请求方法（GET、POST等）
     * @param requestBody 请求体数据（JSON对象）
     * @return 设置好公共参数的请求头
     */
    public HttpHeaders initHttpHeaders(String uri, HttpMethod httpMethod, JsonNode requestBody) {
        String randomIntStr = CommonUtils.genRandomIntStr();
        String timestamp = CommonUtils.calTimestamp();

        //如果是GET请求，请求体设置为空串
        String requestBodyStr = null != requestBody ? CommonUtils.toJson(requestBody) : "";
        String signature = SignatureUtils.sign(SECRET_ID, SECRET_KEY, httpMethod.toString(), randomIntStr, timestamp, uri, requestBodyStr);
        logger.info("签名：{}", signature);

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        headers.setContentType(MediaType.APPLICATION_JSON);

        headers.add("X-TC-Key", SECRET_ID);
        headers.add("X-TC-Nonce", randomIntStr);
        headers.add("X-TC-Timestamp", timestamp);
        headers.add("X-TC-Signature", signature);
        headers.add("AppId", APP_ID);
        headers.add("SdkId", SDK_ID);

        return headers;
    }

}
